const {ccclass, property, requireComponent} = cc._decorator;

@ccclass
@requireComponent(cc.Label)
export default class NickNameLabel extends cc.Component 
{
    @property
    MaxWidth: number = 0;

    private _labelComp: cc.Label = null;

    private get _label(): cc.Label
    {
        if (this._labelComp == null)
        {
            this._labelComp = this.node.getComponent(cc.Label);
        }
        return this._labelComp;
    }

    public set string(value: string) 
    {
        let overflow: cc.Label.Overflow = this._label.overflow;
        value = this.processNickname(value, this.MaxWidth);
        this._label.string = value;
        this._label.overflow = overflow;
    }

    public get string(): string 
    {
        return this._label.string;
    }

    private getTextWidth(text: string): number 
    {
        this._label.string = text;
        // @ts-ignore
        this._label._forceUpdateRenderData();
        return this.node.width;
    }

    private processNickname(nickname: string, max: number): string 
    {
        this._label.overflow = cc.Label.Overflow.NONE;
        let nickNameWidth: number = this.getTextWidth(nickname);
        if (nickNameWidth > max) 
        {
            // 这里使用二分查找来找到最接近且不超出标签宽度的截断位置
            let left: number = 0;
            let right: number = nickname.length;
            let result: number = 0;
            while (left <= right) 
            {
                let mid: number = Math.floor((left + right) / 2);
                let midString: string = nickname.substring(0, mid) + '...';
                let midWidth: number = this.getTextWidth(midString);

                if (midWidth <= max) 
                {
                    result = mid;
                    left = mid + 1;
                } 
                else 
                {
                    right = mid - 1;
                }
            }

            return nickname.substring(0, result) + '...';
        }

        return nickname;
    }
}